#include "gx_touch_driver.h"
#include "gui_task.h"
#include "dev_rgblcd.h"
#include "dev_gt9147.h"
#define MIN_DRAG_DELTA       10

static int last_pos_x;
static int last_pos_y;
static int curpos_x;
static int curpos_y;
static int touch_state;
extern uint8_t get_uart_data(uint8_t *data,uint32_t *len);
extern void set_clear_index(void);
static struct mouse_data mouse_data_t;
uint8_t buf[100] = {0};
uint32_t lenth = 0;
/**************************************************************************/
VOID SendPenDownEvent(VOID)
{
    GX_EVENT event;
    event.gx_event_type = GX_EVENT_PEN_DOWN;
    event.gx_event_payload.gx_event_pointdata.gx_point_x = curpos_x;
    event.gx_event_payload.gx_event_pointdata.gx_point_y = curpos_y;
    event.gx_event_sender = 0;
    event.gx_event_target = 0;
    event.gx_event_display_handle = AT32_SCREEN_HANDLE;
    last_pos_x = curpos_x;
    last_pos_y = curpos_y;
    gx_system_event_send(&event);
}

/**************************************************************************/
VOID SendPenDragEvent(VOID)
{
    GX_EVENT event;
    int x_delta = abs(curpos_x - last_pos_x);
    int y_delta = abs(curpos_y - last_pos_y);

    if (x_delta > MIN_DRAG_DELTA || y_delta > MIN_DRAG_DELTA)
    {
        event.gx_event_type = GX_EVENT_PEN_DRAG;
        event.gx_event_payload.gx_event_pointdata.gx_point_x = curpos_x;
        event.gx_event_payload.gx_event_pointdata.gx_point_y = curpos_y;
        event.gx_event_sender = 0;
        event.gx_event_target = 0;
        event.gx_event_display_handle = AT32_SCREEN_HANDLE;
        last_pos_x = curpos_x;
        last_pos_y = curpos_y;
    
        gx_system_event_fold(&event);
    }
}

/**************************************************************************/
VOID SendPenUpEvent(VOID)
{
    GX_EVENT event;
    event.gx_event_type = GX_EVENT_PEN_UP;
    event.gx_event_payload.gx_event_pointdata.gx_point_x = curpos_x;
    event.gx_event_payload.gx_event_pointdata.gx_point_y = curpos_y;
    event.gx_event_sender = 0;
    event.gx_event_target = 0;
    event.gx_event_display_handle = AT32_SCREEN_HANDLE;
    last_pos_x = curpos_x;
    last_pos_y = curpos_y;
    gx_system_event_send(&event);
}
static uint8_t mouse_read(TS_StateTypeDef *data)
{
    static int16_t last_x = 0;
    static int16_t last_y = 0;
    uint8_t valid = 1;

    int16_t x = 0;
    int16_t y = 0;
	
	if(get_uart_data(buf,&lenth))
	{
		if(mouse_data_t.flag == 0)
        {
            mouse_data_t.flag = 1;
            mouse_data_t.press = buf[0];
            mouse_data_t.x = (uint16_t)((buf[1] << 8) | buf[2]);
            mouse_data_t.y = (uint16_t)((buf[3] << 8) | buf[4]); 
        }
		lenth = 0;
		set_clear_index();	
	}
	
    if (mouse_data_t.flag) {

		x = mouse_data_t.x;
		y = mouse_data_t.y;

        last_x = x;
        last_y = y;
        mouse_data_t.flag = 0;
    } else {
        x = last_x;
        y = last_y;
    }
	data->touchDetected = mouse_data_t.press;
	data->touchX  = x;
	data->touchY = y;
    return 0;	
}

static uint8_t touch_read(TS_StateTypeDef *data)
{
	gt9147_scan();
    if(tp_dev.sta & 0x80)
    {
        data->touchDetected = 1;
    }
	else
	{
		data->touchDetected = 0;
	}
	data->touchX = tp_dev.x[0];
	data->touchY = tp_dev.y[0];
}
	
/*
  *                     ReadBuffer [0]: The Byte count (0x0A)   
  *                     ReadBuffer [1]: X1 coordinate [15,8]  
  *                     ReadBuffer [2]: X1 coordinate [7,0]
  *                     ReadBuffer [3]: Y1 coordinate [15,8]
  *                     ReadBuffer [4]: Y1 coordinate [7,0]
  *                     ReadBuffer [5]: X2 coordinate [15,8]
  *                     ReadBuffer [6]: X2 coordinate [7,0]
  *                     ReadBuffer [7]: Y2 coordinate [15,8]
  *                     ReadBuffer [8]: Y2 coordinate [7,0]
  *                     ReadBuffer [9]: Gesture command (01: Zoom In 02: Zoom out) 
  *                     ReadBuffer [10]: unused byte
*/
VOID  touch_thread_entry(ULONG thread_input)
{

    TS_StateTypeDef TS_State;
    touch_state = TOUCH_STATE_RELEASED;
    
    while(1)
    {
        tx_thread_sleep(10);

//        mouse_read(&TS_State);
		touch_read(&TS_State);
        if (!(TS_State.touchDetected))
        {
            // no touch, check so see if last was touched
            if (touch_state == TOUCH_STATE_TOUCHED)
            {
                touch_state = TOUCH_STATE_RELEASED;
                SendPenUpEvent();
            }
        }
        else
        {
//			printf("x:%d y:%d \r\n",TS_State.touchX,TS_State.touchY);
            if (TS_State.touchX > LCD_WIDTH ||
                TS_State.touchY > LCD_HEIGHT)
                continue;

            // screen is touched, update coords:
            curpos_x = TS_State.touchX;
            
            curpos_y = TS_State.touchY;
            if (touch_state == TOUCH_STATE_RELEASED)
            {
                touch_state = TOUCH_STATE_TOUCHED;
                SendPenDownEvent();
            }
            else
            {
                // test and send pen drag
                SendPenDragEvent();
            }
        }
    }
}
